//xuejianxinokok@163.com  20190927
(function (window){
console.info("%c 系统名称:Springboot2 \n 版    本:%d\n 作    者:%s","color:red",2019,"xuejianxinokok@163.com");
var AppContext={
		 webPath  :"/"      //静态文件路径 主要用于区分动静分离是路径不一致
		,rootPath :"/" 
		,toJson           :function (obj) {return JSON.stringify(obj);}/*js对象转化为json字符串*/
		,parseJson        :function (json){return JSON.parse(json);}/*json字符串转化为js对象*/
		,deleteUser       :function ()    {this.removeItem("user");}/*设置用户*/
		,setUser          :function (user){delete user.menuIds; delete user.password;this._user=user;this.setItem("user",this.toJson(user));}/*设置用户*/
		,getUser          :function ()    {if(this._user){return this._user; } else{ return this.parseJson(this.getItem("user"));}}/*获取当前用户信息*/
		,setItem          :function (k,v) {sessionStorage.setItem(k, v);}/*设置 sessionStorage 变量*/
		,removeItem       :function (k)   {sessionStorage.removeItem(k);}/*移除sessionStorage 变量*/
		,getItem          :function (k)   {return sessionStorage.getItem(k);}/*获取 sessionStorage 变量*/
		,setLocalItem     :function (k,v) {localStorage.setItem(k, v);}/*设置 localStorage 变量*/
		,removeLocalItem  :function (k)   {localStorage.removeItem(k);}/*移除localStorage 变量*/
		,getLocalItem     :function (k)   {return localStorage.getItem(k);}/*获取 localStorage 变量*/
	    ,loadComponentAsyn:function (url,context) {
    		 return function(){//返回一个函数
    			         //vue 组件配置对象
    				     var config=  {
    				        /** 要渲染的异步组件，必须是一个Promise对象，可以在加载前【验证权限】 */
    				        component: new Promise (function (resolve, reject){
    						  var ps={accept:'text/html,text/plain'};
    						  Vue.http.defaults.baseURL=AppContext.webPath; //此处需要从web目录加载
    						  var t=new Date().getTime();//请求时添加时间戳防止缓存
    						  Vue.http.get(url+"?t="+t,ps).then((response)=>{
    							  //加载页面模板
    							  var html_js= response.data;
    							  //.不能匹配空白字符和回车符,[\s\S]*用代替, m表示多行 ,占时没有处理<!--注解问题 -->
    							  var reg=/([\s\S]*)<script>([\s\S]*)<\/script>/mi;
    							  var result=reg.exec(html_js);
    							  var html=result[1];//提取html模板
    							  var js=result[2];//提取js
    							  //获取自定义选项
    							  var myOptions= context||{};
    							  //console.log(myOptions);
    							  //获取初始化组件函数
    							  try{
    								// 有时候一些非常动态的代码是以字符串的形式通过 eval() 函数在当前 Javascript context 中创建出来，而不是作为一个独立的 js 文件加载的。
    								// 这样你在左边的内容区就找不到这个文件,因此很难调试.其实我们只要在 eval 创建的代码末尾添加一行 "//@ sourceURL=name" 就可以给这段代码命名（浏览器会特殊对待这种特殊形式的注释），
    								// 这样它就会出现在左侧的内容区了,就好像你加载了一个指定名字的 js 文件一样，可以设置断点和调试了。下图中，我们通过 eval 执行了一段代码，并利用 sourceURL 将它命名为 dynamicScript.js ，
    								// 执行后左侧内容区就出现了这个“文件”，而它的内容就是 eval 的中的内容。
    								// 注意在 (no domain) 下可以看到
    								/*
    								  (function(){
    									           function _init(context){
    									             //组件初始化逻辑
    										       }
    								              return _init ; 
    								             }
    								  )();
    								*/
    								  var newJs="(function(){ \r\n"+js+" \r\n return _init ; })(); \r\n //@ sourceURL="+url+".js";
    								  var initComponent= eval(newJs);
    								  //执行函数,返回配置
    								  var defautOptions= initComponent(myOptions);
    								  //设置组件模板
    								  defautOptions.template=html;
    								  //渲染组件
    								  resolve(defautOptions);
    							  }catch(e){
    								  console.error(e);
    								  alert('加载'+url+'组件错误:'+e.message);
    							  }
    							  Vue.http.defaults.baseURL=AppContext.rootPath; 
    						  });
    					   }),
    				        /* 加载过程中显示的组件 */
    				        loading: {
    				            template: '<p>加载中...</p>'
    				        },
    				        /* 出现错误时显示的组件  */
    				        error: {
    				            template: '\
    				                <p style="color:red;">load failed!</p>\
    				            '
    				        },
    				        /* loading组件的延迟时间 */
    				        delay: 10,
    				        /* 最长等待时间，如果超过此时间，将显示error组件。 */
    				        timeout:3200
    				    };
    				    return config;
    		}
      },
      loadComponent:function (url,options){
    	  return (this.loadComponentAsyn(url,options))();
      }
};//AppContext
//导出为全局变量
function _export(k,v){window[k]=v;}

Vue.http=Vue.axios;
Vue.axios.defaults.baseURL=AppContext.rootPath;

//请求拦截器
Vue.http.interceptors.request.use(request=>{
	   loading.show();
	   //对请求做些处理
	   //console.log(request);
	   //添加请求头
	   //if(store.state.user.token){ request.headers.Authorization='token'; };
	   return request;
	}
	,e=>{
	   __alert(e.message);
	   console.error(e);
	   loading.hide();
	   return new Promise(() => {});
	}
);
//相应拦击器
Vue.http.interceptors.response.use(
		response=> {
			//对响应做些处理
			//console.log(response);
			loading.hide();
			//请求html,用于异步加载组件
			if( response.headers['content-type'] && response.headers['content-type'] =='text/html'){
				return response;
			}
			
			//普通ajax请求，请求数据
			var result=response.data;
  	        if(!result.success){//数据格式是统一的
  	        	__alert(result.message);
  	        	//return new Promise(() => {}) ;//终止执行
  	        	return Promise.reject(result);
  	        }else{
			    //直接返回数据data部分
			    return result.data;
  	        }
			
		}
		,e=>{
			__alert(e.message);
			console.error(e);
			loading.hide();
			return new Promise(() => {}) ;//终止执行
		}
);




var loading={
	_id:'#_loading_div'
	,show: function (){
			var obj=document.querySelector(this._id); 
			if(!obj){document.body.insertAdjacentHTML('beforeend', this._html);  obj=document.querySelector(this._id); } 
			obj.style.display='block';
	},
	hide:function(){var obj=document.querySelector(this._id); if(obj){  obj.style.display='none';} }
	,_html:'<div id="_loading_div" style="display:none;position:fixed;top:30%;left:45%"><img alt="加载中..." src="'+AppContext.webPath+'resources/files/assets/images/loader.gif"><div>'
}

//基础混入
var appBase={
	methods: {//全局方法用$开头
		_alert  :function (msg,callback){
			this.$bvModal.msgBoxOk(msg, {
		          title: '提示',
		          size: 'sm',
		          buttonSize: 'sm',
		          okVariant: 'success',
		          headerClass: 'p-2 border-bottom-0',
		          footerClass: 'p-2 border-top-0',
		          centered: true
		        })
		        .then(value => {
		        	 callback( value);
		        })
		        .catch(e => {
		        	console.error(e);
		        })
		},
		_confirm:function (msg,callback) {
	          this.$bvModal.msgBoxConfirm(msg, {
	            title: '请确认',
	            size: 'sm',
	            buttonSize: 'sm',
	            okVariant: 'danger',
	            okTitle: '确定',
	            cancelTitle: '取消',
	            headerClass: 'p-2 border-bottom-0',
	            footerClass: 'p-2 border-top-0',
	            hideHeaderClose: true
	            //,centered: true  //弹出位置
	          })
	          .then(value => {
	        	   callback( value);
	          })
	          .catch(e => {
	              console.error(e);
	          });
	    },
	    //提示信息
	    _toast:function(toaster, delay=1000) {
	          this.$bvToast.toast(`${toaster}`, {
	            //title: '操作提示',
	            toaster: 'b-toaster-top-center',
	            solid: true,         //不透明
	            //variant: danger,
	            noCloseButton:true,  //不显示关闭按钮
	            autoHideDelay:delay, //延迟关闭时间
	            //noAutoHide:true,   //不自动关闭
	            //appendToast: true, //尾部追加
	            solid :true
	          })
	    },
	    doPost:function(url,ps,successCallback,errorCallback){
	    	this.$http.post(url,ps).then((data)=> {if(successCallback){ successCallback(data);}}).catch(e=>{if(errorCallback){ errorCallback(e);} else {console.error(e);}});
	    },
	    doGet :function(url,successCallback,errorCallback){
	    	this.$http.get(url).then((data)=> {if(successCallback){ successCallback(data);}}).catch(e=>{if(errorCallback){ errorCallback(e);} else {console.error(e);}});
	    }
	}
};



//基础列表
var appList={
		 mixins: [appBase]
        //,template: '#listTemplate' 
        ,data:function(){
        	return	{
        		 overrideMounted:false //是否覆盖父类mounted方法
    	        ,ps:{//查询和分页的参数
    	        	 pageSize: 10
    		        ,total   : 0  //总条数
    		        ,pageNum : 1  //当前页数
    	        }
    	        ,list: [] //数据
    	        ,selected: [] //选中的数据
    	        ,vo:{}   //添加或编辑的对象
    	        ,fields: []//字段说明
        	}
        }
		,mounted: function() {
			if(!this.overrideMounted){
			   if(this.$route.params.ps){//如果是从查看和编辑页面返回的话会待会参数
				   this.ps=this.$route.params.ps;
			   }
			   this.listPage();//加载时加载列表
			}
		}
		,methods:{
			 getListPageUrl:function(){
				return  "/";
			 },
			 getDoRemoveUrl:function(){
				return "/";
			 },
			 query   :function(){
				 this.ps.pageNum=1; 
				 this.listPage();
			 },
			 listPage:function(){
				  var that=this;
				  console.log(this.ps.pageNum);
				  this.doPost(this.getListPageUrl(),this.ps,(data)=> {
			  	      ({list:that.list,total:that.ps.total}=data);//外层(括号)是必须的
					  //this.list=data.list;
					  //this.ps.total=data.total;
			      });
			 }	 
			 ,onRowSelected(items) {
			   this.selected = items;//选中行
			 }
			 ,selectTo:function(routeName,selectIndex){//选中并跳转
				  if( Number.isInteger(selectIndex)){
					  this.selected[0]=this.list[selectIndex];
				  }
				  if(this.selected.length==1){
				      this.vo=this.selected[0]; //把选中的第一行数据设置为当前编辑对象
				      //vo 用于传递查询数据,ps用于传递查询参数,返回时需要锁定所在页
			          this.$router.push({ name: routeName, params: {vo:this.vo, ps:this.ps}});
				  }else{
					  this._toast('请选择1行数据！');
				  }
			 }
			 ,toAdd:function(){
				  this.$router.push({ name: 'add'});// 切换到add
			 }
			 ,toView:function(index){
				  this.selectTo('view',index);
			 }
			 ,toEdit:function(index){
				  this.selectTo('edit',index);
			 }
			 ,doRemove:function(index){
				  if(Number.isInteger(index)){
					  //this.$refs.listTable.selectRow(index);
					  this.selected[0]=this.list[index];
				  }

				  if(this.selected.length<1){
					  this._toast('请选择要删除的数据！');
					  return ;
				  }
				  this._confirm('共'+this.selected.length+'行数据,确认删除吗?',ok=>{
					  if(ok){
			 		    	var ps=[];
			 	    	    this.selected.forEach((item)=>{ ps.push(item.id); })
			 		    	this.doPost(this.getDoRemoveUrl(),ps,(data)=> {
			 		      	    this._toast('操作成功','success');
			 		      	    this.listPage();//刷新列表
			 		        });
			 		  }
				  });
			 }
			 ,checkAll:function(checked) {
			      if(checked){
			    	  this.$refs.listTable.selectAllRows();
			      }else{
			    	  this.$refs.listTable.clearSelected();
			      }
			  }
			}
};

var appAdd={
	 mixins: [appBase]
     ,data:function (){
	   return {vo:{} };
	 }
	,methods:{
		getSaveUrl:function (){
			 return "/";
		},
		onSubmit:function() {
			 var ps=this.vo;
			 this.doSave(this.getSaveUrl(),ps);
		}
	    ,toList(){
	    	this.$router.push({ name: 'list',params:{ps:this.$route.params.ps}} );
	    }
	    ,buttonDisalbed:function (disalbed){
	    	this.$refs.btnSubmit.disabled=disalbed;
	    }
	    ,beforeSave:function(){
	    	this.buttonDisalbed(true);
	    }
	    ,onSaveSuccess :function(data){
	    	this.buttonDisalbed(false);
	      	this.toList();
	    }
	    ,onSaveError   :function(err){
	    	this.buttonDisalbed(false);
	    }
	    ,validate      :function(ps){return true;}
	    ,doSave:function (url,ps){
	      if(!this.validate){ return false ;};
	      this.beforeSave();
		  this.doPost(url,ps,this.onSaveSuccess,this.onSaveError);
	    }
	}
}



var appView={
		 mixins: [appAdd]
        ,data:function (){
        	return{overrideMounted:false }
   	    }
		,mounted: function() {
			if(!this.overrideMounted){
		   	  var vo=this.$route.params.vo;
		   	  this.loadVo(vo);
			}
		}
		,methods:{
			getLoadVoUrl:function (){
				 return "/";
			},
			loadVo:function (ps){
		      	 this.doPost(this.getLoadVoUrl(),ps,(data) =>{this.vo=data;});
		    }
		}
}


var appEdit={
		mixins: [appView]
}



//全局vue用于提供全局对话框
let gvm = new Vue({mixins: [appBase]} );
function __alert(msg, delay=3000){
	gvm._toast(msg,delay);
}



_export('AppContext',AppContext);
_export('appList',appList);
_export('appAdd',appAdd);
_export('appView',appView);


/*function vueTouch(el, type, binding) {
    this.el = el;
    this.type = type;
    this.binding = binding;
    var hammertime = new Hammer(this.el);
    hammertime.on(this.type, this.binding.value);
};
Vue.directive("tap", {
    bind : function(el, binding) {
        new vueTouch(el, "tap", binding);
    }
});
Vue.directive("swipeleft", {
    bind : function(el, binding) {
        new vueTouch(el, "swipeleft", binding);
    }
});
Vue.directive("swiperight", {
    bind : function(el, binding) {
        new vueTouch(el, "swiperight", binding);
    }
});
Vue.directive("press", {
    bind : function(el, binding) {
        new vueTouch(el, "press", binding);
    }
});	
*/

})(window);

